import { Component, ComponentType } from "./Component";
import { must, any } from "../core/logic";
import { Register } from "../register/Register";
import { ids } from "../core/ids";
/**
 * 渲染组件
 * @class
 * @extends w.component.Component
 * @memberof w.component
 */
class Mesh extends Component {
    /**
     * @constructor
     * @param {w.geometry.Geometry} opts.geometry 【必选】几何体。
     * @param {w.material.Material} opts.material 【必选】材质。
     */
    constructor(opts = {}) {
        opts.type = any(opts.type, ComponentType.Mesh);
        opts.id = ids.generate();//生成颜色id
        super(opts);
        this.geometry = must(opts.geometry);
        this.material = must(opts.material);
        this.visibility = any(opts.visibility, true);
        this._hash = '';
        this.autoUpdate = true;
        this.update();
    }
    updateState() {
        this.setState(this.geometry.getState() && this.material.getState());
    }
    updateHash() {
        if (this.geometry && this.material) {
            this._hash = this.geometry.hash + this.material.hash;
        }
    }
    get hash() {
        return this._hash;
    }
    set geometry(v) {
        this._geometry = v;
        this._geometry.bind(this);
        this.update();
        return this;
    }

    get geometry() {
        return this._geometry;
    }

    set material(v) {
        this._material = v;
        this._material.bind(this);
        this.update();
        return this;
    }

    get material() {
        return this._material;
    }

    set visibility(v) {
        this._visibility = v;
        this.update();
        return this;
    }

    get visibility() {
        return this._visibility;
    }
    set shine(v) {
        this._shine = v;
        this.update();
        return this;
    }

    get shine() {
        return this._shine;
    }
    destroy() {
        let flag = super.destroy();
        this.geometry.unBind(this);
        this.material.unBind(this);
        if (flag) {
            this.material.destroy();
            this.geometry.destroy();
            const meshRender = Register.instance.manager(ComponentType.MeshRender).get('x');
            let renderInfo = meshRender.get(this.id)
            if (renderInfo) {
                meshRender.remove(renderInfo);
                ids.recovery(this.id);//收回id
            }

        }
        return flag;
    }
    toGPU() {
        this.material.toGPU();
        //根据材质类型不同，分别写入idColor
        if (this.material.materialType == "BasicMaterial") {
            this.material.getParam('material').buffer(ids.toColor(this.id), 96,);
        } else if (this.material.materialType == "StandardMaterial") {
            this.material.getParam('material').buffer(ids.toColor(this.id), 64);
        }
        let { defs, config, grouplayouts2, bindGroup2, grouplayouts3, bindGroup3 } = this.material
        this.kk = defs
        this.geometry.toGPU();
        let defGeometry = this.geometry.defs
        let configGeometry = this.geometry.config
        let { vertexBuffer, geometryParams, geometryEntriesGroup, geometrEntriesLayout } = this.geometry
        this.defs = { ...defs, ...defGeometry }
        this.config = { ...config, ...configGeometry }
        if (grouplayouts2) this.grouplayouts2 = grouplayouts2
        if (bindGroup2) this.bindGroup2 = bindGroup2
        if (grouplayouts3) this.grouplayouts3 = grouplayouts3
        if (bindGroup3) this.bindGroup3 = bindGroup3
        if (geometryEntriesGroup?.length > 0) this.geometryEntriesGroup = geometryEntriesGroup
        if (geometrEntriesLayout?.length > 0) this.geometrEntriesLayout = geometrEntriesLayout
        if (vertexBuffer) this.vertexBuffer = vertexBuffer
        if (geometryParams) this.geometryParams = geometryParams
    }
}

export { Mesh }
